UniverseRuler, в доте 6-6 использованы игроки 13 и 14
тебе нужно просто сохранять приказ отданный триггерно(ты ведь ими будешь юнитами управлять)
и восстанавливать его при получение приказа для игрока
для этого нужна буленовская переменная для определения триггерный это приказ или нет
и структура/хэш/юзердата для сохранения приказа UniverseRuler:
еще остались асы картостроения, но а сейчас начинаю думать, что их все таки нету
если ас картостроения это человек который воплощает все ваши фантазии в жизнь то тут таких нету и не было
ещё можно создавать всех юнитов за 1 резервного игрока
а автоатаку делать триггерно
этот вариант самый лучший но то просто не сможешь его сделать
ибо нужны джасс+алгоритмы+структуры/хэш
а ты судя по всему ничего из этого не знаешь
делаем спелл на основе канала
при применении этого спелла выбираем всех юнитов в радиусе R от юнита применившего спелл и имеющих того же владельца что и юнит применивший заклинания
и переносим их в точку каста
где R это радиус захвата юнитов для телепортации
спецэффекты по вкусу
это если массовая телепортация (герой + юниты рядом с ним)
если только герой то как сказали выше
Каждый раз по прошествии этого самого определённого промежутка времени пикаешь (Отряд - Pick Every units...) нужных (всех?) тебе юнитов, при условии что они находятся в нужной области, а после мгновенно перемещаешь в другую область.
Таймер кончается, все герои которые не находятся на арене - телепортируются на неё. В это же время в области создаётся нужное количество мобов и мегамоб(босс).
Окончание раунда, точно ещё не разобрался
Делаешь, наверное, неправильно. Сначала тебе нужно выделить те декорации (копировать, вырезать), потом жмешь вставить (у тебя появится возможность выбрать место, куда ты их хочешь поставить, будут видны сами объекты, которые двигаются за курсором мыши). После этого ничего не жмешь и идешь в пункт Правка и жмешь Повернуть.../Отразить..., как тебе нужно, и только после всего этого ставишь на карту повернутый вариант.
bOrissko, Почти, я создавал карту на рабочем столе а оказалось что менять тайлсеты можно только в папке maps. Но сделать обрыв в бездну и обрыв затонувшего города так и не получилось(
Bornikkeny, сделал специально чтобы доказать тебе что ты несёшь бред
даже 2 скрина приложил
думаю закинуть библиотеки сможешь сам (в папку *твой jngp*\AdicHelper\lib)
Хорошо группы реализуешь как альтернативу unit[array]. Я тоже самое получил. nvc123, и всё же твой хук не тот что мне нужен.
Я решил проблему, спасибо что дал идею обрабатывать движение внутри структуры, а не в стеке.
кот
library Hook initializer Init_Hook uses LibMath
globals
mhook ahook[100]
integer ihook = -1
endglobals
struct mhook
unit host = null
unit target = null
real face = 0
real speed = 0
real dis = 0
real dismax = 0
integer chaini = 0
unit chain[50]
real scale = 0
integer move = 1
integer i = 0
static method Create takes unit host, real tx, real ty, real scale returns mhook
local mhook h = mhook.create()
local integer i = GetPlayerId(GetOwningPlayer(host))
local real x = GetUnitX(host)
local real y = GetUnitY(host)
local real f = GetAngleXY(x,y,tx,ty)
set h.host = host
set h.face = f
set h.speed = 600
set h.dismax = 1400
set h.scale = scale
set h.chain[0] = CreateUnit(Player(i),'h007',GetPolarX(GetUnitX(host),f,h.scale/2),GetPolarY(GetUnitY(host),f,h.scale/2),f)
set h.i = i
call UnitAddAbility(h.chain[0],'Amrf')
call UnitAddAbility(h.chain[0],'Amrf')
call SetUnitFlyHeight(h.chain[0],50,0)
call SetUnitPathing(h.chain[0],false)
return h
endmethod
method Start takes nothing returns boolean
if ihook < 1000 then
set ihook = ihook + 1
set ahook[ihook] = this
return true
else
return false
endif
endmethod
method Destroy takes nothing returns nothing
local integer i = 0
loop
exitwhen i > ihook
if ahook[i] == this then
set ahook[i] = ahook[ihook]
set ahook[ihook] = 0
set ihook = ihook - 1
set i = ihook // выход из цикла
endif
set i = i + 1
endloop
set this.target = null
set this.host = null
call this.destroy()
endmethod
method Move takes nothing returns nothing
local integer i1 = 0
local integer l = 0
local real x
local real y
local real xh
local real yh
local real f
if move == 1
set dis = dis + speed*0.025
loop
exitwhen i1 > .chaini
set x = GetUnitX(.chain[i1])
set y = GetUnitY(.chain[i1])
if i1 > 0 then
set f = GetAngleXY(x,y,GetUnitX(.chain[i1-1]),GetUnitY(.chain[i1-1]))
call SetUnitX(.chain[i1],GetPolarX(x,f,.speed*0.025))
call SetUnitY(.chain[i1],GetPolarY(y,f,.speed*0.025))
else
set f = face
call SetUnitX(chain[i1],GetPolarX(x,f,.speed*0.025))
call SetUnitY(chain[i1],GetPolarY(y,f,.speed*0.025))
endif
call SetUnitFacing(chain[i1],f)
set i1 = i1 + 1
endloop
set x = GetUnitX(chain[chaini])
set y = GetUnitY(chain[chaini])
set f = GetAngleXY(GetUnitX(.host),GetUnitY(.host),x,y)
set xh = GetPolarX(GetUnitX(.host),f,.scale/2)
set yh = GetPolarY(GetUnitY(.host),f,.scale/2)
//Create==================
if GetDisXY(xh,yh,x,y) >= .scale/2 then
set chaini = chaini + 1
set chain[chaini] = CreateUnit(Player(.i),'h007',xh,yh,f)
call UnitAddAbility(.chain[.chaini],'Amrf')
call UnitAddAbility(.chain[.chaini],'Amrf')
call SetUnitFlyHeight(.chain[.chaini],50,0)
endif
if dis > dismax then
set move = 0
endif
else
//REVERSE=============
set xh = GetUnitX(host)
set yh = GetUnitY(host)
set chain[chaini+1] = host
loop
exitwhen l > chaini
set x = GetUnitX(chain[l])
set y = GetUnitY(chain[l])
//if chain[chaini] == null then
// set f = GetAngleXY()
//endif
set f = GetAngleXY(x,y,GetUnitX(chain[l+1]),GetUnitY(chain[l+1]))
call SetUnitX(chain[l],GetPolarX(x,f,speed*0.025))
call SetUnitY(chain[l],GetPolarY(y,f,speed*0.025))
call SetUnitFacing(chain[l],f-180)
set l = l + 1
endloop
//Destroy==================
set x = GetUnitX(chain[chaini])
set y = GetUnitY(chain[chaini])
set xh = GetUnitX(host)
set yh = GetUnitY(host)
if GetDisXY(GetUnitX(chain[chaini]),GetUnitY(chain[chaini]),GetUnitX(host),GetUnitY(host)) < 100 then
call RemoveUnit(chain[chaini])
set chain[chaini] = null
set chaini = chaini - 1
if chaini == -1 then
call .Destroy()
endif
endif
endif
endmethod
endstruct
private function Engine takes nothing returns nothing
local integer i = 0
local mhook h
local group g
local unit t
loop
exitwhen i > ihook
if ahook[i] != 0 then
set h = ahook[i]
//--run--//
call h.Move()
else
set ahook[i] = ahook[ihook]
set ahook[ihook] = 0
set ihook = ihook - 1
set i = i - 1
endif
set i = i + 1
endloop
//call DestroyGroup(g)
set g = null
set t = null
endfunction
function Trig_HookC_Bool takes nothing returns boolean
if GetSpellAbilityId() == 'A01D' then //Способность Мясной хук
return true
else
return false
endif
endfunction
function Trig_HookC_Actions takes nothing returns nothing
local mhook h
set h = mhook.Create(GetSpellAbilityUnit(),GetSpellTargetX(),GetSpellTargetY(),110)
call h.Start()
endfunction
function Init_Hook takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddAction( t, function Trig_HookC_Actions )
call TriggerAddCondition(t,function Trig_HookC_Bool)
call TimerStart(CreateTimer(),0.025,true,function Engine)
endfunction
endlibrary
А если создать дамми-юнитов каждого типа? Попробуй как-то так: Триггер 1
Событие - Игрок выбрал юнита
Условие - Триггерный игрок не равен игроку-владельцу триггерного юнита
Действие:
Записать триггерного юнита в переменную из массива U[номер триггерного игрока];
сменить владельца юнита-дамми (можно через базу данных сделать и вычислять по типу выбранного юнита) на триггерного игрока;
выбрать юнита-дамми для триггерного игрока;
установить юниту-дамми Custom Value = номеру триггерного игрока Триггер 2
Событие - Юнит получил приказ без цели
Условие - Custom Value триггерного юнита больше 0
Действие - Приказать юниту U[Custom Value триггерного юнита] выполнить приказ ("полученный приказ") Триггер 3
Событие - Игрок отменяет выбор юнита
Условие - Custom Value триггерного юнита больше 0
Действие - Установить триггерному юниту Custom Value = 0
Ещё можно сделать дамми-юнитов зданиями с набором только тех способностей, которые можно активировать.
P.S. Есть один недостаток у этой системы - кулдаун способностей. Не знаю, как его синхронизировать. Разве что делать дамми для каждого конкретного юнита или использовать мемхак. Но если автор умеет его использовать, то это он мне советы давать должен, а не наоборот =)
Drulia_san, Ну да.
Добавляешь аурку - вот тебе баф на юните. Самый простой способ как по мне.
+Можно эффекты настроить, что вполне неплохо. Пока висит фейковый баф(наша аура) - на юните есть эффект.
Через дамми касты я пробовал, но долго+муторно+подключается дамми система = +лаги и местами утечки.
Насчёт таймаута - это уже по самим спеллам, я долго мучался чтобы оно всё работало как надо и не оверлапалось
Вот такой штукой у меня удаляется баф:
public function unitRemoveAbilityandBuffBY(unit u,integer dhv,integer mLv) returns boolean
boolean b=UnitRemoveAbility(u,dhv)
UnitMakeAbilityPermanent(u,false,dhv)
UnitRemoveAbility(u,mLv)
return b
]]Chupakabra[[, я понял. Крч на костылях придется лепить. Попробуй при выборе героя добавлять геройские абилки, а потом блочить или удалять их. Думаю, так можно добавить до 7 штук. Через ро не получается больше 5.
Если не получится - пробуй делать полностью триггерно с помощью спеллбука.
PT153, это лимит для одного игрока, то есть героя смогут нанять другие.
Нужно поставить таверне способность Продажа войск. Потом делаешь триггер:
Событие: Юнит вошёл в область (Вся игровая карта)
Условие: Триггеринг юнит равно Герой равно Да (можно этого не делать, просто исключает срабатывание триггера для каждого юнита)
Действия: несколько действий Если/То/Иначе
Если - Юнит тип (Триггеринг юнит) равно Какой-то Герой Из Таверны
То - Нейтральное здание - Удалить Какой-то Герой Из Таверны из таверны
Иначе - Ничего
И так для каждого типа героев в таверне.
Условие - твой герой имеет в статусе баф от нужной способности (можно сделать на базе Жара прейсподней с нулевыми параметрами)
Действие - Проверяем есть ли у героя необходимая мана - если да - то продолжать цикл, если нет - давать приказ - выключить твою способность. Создавать дамми-юнита __(в виде огненного шара к примеру)__и на большой скорости запускать его в направлении куда сморит герой, плюс минус 5 градусов. Давать даммику таймер уничтожения где-то 0.2-0.4 секунды, его можно повышать с уровнем способности - так огненное дыхание будет дальше при вкачивании.
Получается что в секунду триггер будет выпускать 20-25 огненных шаров с небольшими попровками на углу движения - в результате эффект огненной волны, получится и красиво и здорово.
Конечно нужно еще создать триггер, который будет отлавливать налетел ли на кого-то твой огненный шар - и наносить урон.
Кстати только потом подумал)) можно не заморачиваться насчет затрат маны и её пересчета. Можно прямо в способности жара прейсподней поставить затраты на применение и кастование, в триггере можно условия эти убрать.
может скинешь карту удали все что не связанно с предметами посмотрим что не так.
Вот скрин одного из предметов, который перестал работать. Boots of Travel - активка. Мне кажется это просто баг, так как перестает работать какой-то предмет, на самом деле, очень редко. Я думал может есть какое то логическое объяснение, но увы.
Спасибо за ответы.
Делай мвссив с индексом равным номеру игрока (чтоб не запутаться) При событии ставь условие на триггеринг игрока. Если триггенинг игрок = красный то перекидывай соотв. юнита по индексу. напр MyHero[1]. Используй if then else. Все вместится в 1 триггер с кол-вом событий равным кол-ву игроков.
первое без триггеров не убрать, нужно создать условие, где изучаено исследование, и действие где ты выполняешь над юнитом действие, удалить способность.
НА счет второго, есть такое исследование, по мойму называется "темный", из первой части 3 варика. в его параметрах указываешь войско и на какие меняются, ну и уже его пихаешь в домик и изучаешь
ТЬФУ! Никто, начиная с меня, JASS читать не умеет!
call SetAbilityCD (GetSpellAbilityId(), i, GetAbilityCD(GetSpellAbilityId(), GetUnitAbilityLevelSwapped(GetSpellAbilityId(), GetTriggerUnit())) * percent)
на русский переводится как:
Задать перезарядку способности (Кастуемая способность, уровень i, получить перезарядку способности юнита на ТЕКУЩЕМ УРОВНЕ СПОСОБНОСТИ ЮНИТА и умножить на нашу переменную)
Какого хрена тут ТЕКУЩИЙ УРОВЕНЬ, когда должен тоже быть уровень i?! Оно в цикле везде берет текущий уровень абилки вмеcто i. Т. е. если перезарядка на разных уровнях разная, это уже ппц ошибка.
Сейчас как раз фикшу эту абилу, она один хрен не до конца правильно действует, и уже тут самые разные извращения с ней получались, после выхода из вара фаталило, крч, 90% вероятности, что другие абилы Психопомпы в поряде, а фатал здесь.
Короче, вот, вроде теперь действует нормально.
Извините уж, что не под катом, мозги уже не имеют сил кат вставлять.
function BendingEffect takes nothing returns nothing
local real percent = 1.00
local real percent2 = 0.00
local integer i = 11
local integer percentchange = 0
if ( GetUnitAbilityLevelSwapped(GetSpellAbilityId(), GetTriggerUnit()) >= 1 ) and (GetAbilityCD(GetSpellAbilityId(), GetUnitAbilityLevelSwapped(GetSpellAbilityId(), GetTriggerUnit())) >= 1) then
УВЕЛИЧЕНИЕ НА 1%
if UnitHasBuffBJ(GetTriggerUnit(),'B0H8') == true then
set percent = 1.01
endif НА 1% - ЗАКРЫТО.
УВЕЛИЧЕНИЕ НА 2%
if UnitHasBuffBJ(GetTriggerUnit(),'B0H9') == true then
set percent = 1.02
endif НА 2% - ЗАКРЫТО.
УВЕЛИЧЕНИЕ НА 3%
if UnitHasBuffBJ(GetTriggerUnit(),'B0HA') == true then
set percent = 1.03
endif НА 3% - ЗАКРЫТО.
УВЕЛИЧЕНИЕ НА 4%
if UnitHasBuffBJ(GetTriggerUnit(),'B0HB') == true then
set percent = 1.04
endif НА 4% - ЗАКРЫТО.
УВЕЛИЧЕНИЕ НА 5%
if UnitHasBuffBJ(GetTriggerUnit(),'B0HC') == true then
set percent = 1.05
endif НА 5% - ЗАКРЫТО.
ТАЛАНТ СИЛЬНОЕ ИСКРИВЛЕНИЕ
set i = 0
set percent = percent - 1
loop
set i = i + 1
exitwhen i > 12
if ( GetUnitAbilityLevelSwapped('A281', udg_Circle[i]) == 2 ) then
set percent = percent * 2
set i = 12
endif
endloop
set percent = percent + 1 ТАЛАНТ СИЛЬНОЕ ИСКРИВЛЕНИЕ - ЗАКРЫТО.
ОКРУГЛЕНИЕ ДО СОТЫХ (ИНАЧЕ МОГУТ ЗАПИСАТЬСЯ ДОП. ЦИФРЫ НЕ В ТЕ ЯЧЕЙКИ)
loop
exitwhen i < 1
set i=i - 1
set percent2 = GetAbilityCD(GetSpellAbilityId(), i) * percent
set percent2 = percent2 * 100
set percentchange = R2I(percent2)
set percent2 = I2R(percentchange)
set percent2 = percent2 * 0.01
call SetAbilityCD(GetSpellAbilityId() , i , percent2)
endloop
ОКРУГЛЕНИЕ ДО СОТЫХ - ЗАКРЫТО.
endloop
else
endif
else
endif
endfunction
//////////////
Ну, короче, действует-то однозначно она уже лучше, раньше цифры высчитывались с избытком, теперь явно правильнее. Насчет фаталов время покажет... Но все равно стало лучше.
Obelick, У Труповозки есть заклинание (кастомное) "Сбросить труп" наносит урон по области. Так вот я хочу ,чтоб при применении этого заклинания у Труповозки тратился один труп из тех что она имеет,а если не имеет трупов то и заклинание применить нельзя.
дать труповозке кастом велью (или свою переменную, если труповозок больше чем 1 - массив с индеком или опять кастом велью) по количеству трупов не? если ты используешь гулей как боевые единицы, создай их кастомную копию и используй её, а появление натурального гуля (или его трупа) уже отлавливай Maxim53:
Obelick, У Труповозки есть заклинание (кастомное) "Сбросить труп" наносит урон по области. Так вот я хочу ,чтоб при применении этого заклинания у Труповозки тратился один труп из тех что она имеет,а если не имеет трупов то и заклинание применить нельзя.
собсно, порывшись в редакторе, есть идея насчет выброски трупа - дать труповозке запрещенный спеллбук со стандратным скиллом Drop Corpse и дать приказ на его каст, как только прокастует - дать команду Stop, чтобы больше 1 трупа не вылетело. И я не знаю как отследить выброшенный труп, потому что его нужно будет сразу удалить из игры, а если трупов в округе больше 1 - конкретно выброшенный твоей труповозкой отследить не представляется мне возможным Maxim53:
Obelick, У Труповозки есть заклинание (кастомное) "Сбросить труп" наносит урон по области. Так вот я хочу ,чтоб при применении этого заклинания у Труповозки тратился один труп из тех что она имеет,а если не имеет трупов то и заклинание применить нельзя.
можешь дать труповозке ману без регена, и скилл наподобие того что у гулей (я...ням-ням..кушать....людей), когда они едят трупы, и за каждый съеденный давать 1 ману, а при касте - тратить или сразу манакост в 1 выставить. Если у тебя есть восстановители маны - опять таки вводить массив\кастом велью по количеству трупов и периодически устанавливать ману в его значение, но это немного бажно, ибо становится возможен каст без наличия трупа. Obelick:
Что? Какое заклинание? Ты не написал, что именно тебе надо. Ты хочешь сделать заклинание труповозки триггерно? Или что? Трупы в ней - это вурдулаки, загруженные как на корабль. Выбрать трупы тоже можно, есть где-то в условиях.
выбрать трупы внутри труповозки нельзя, насколько я сейчас понял. даже если внести всех жмуриков на карте в массив - у труповозки есть способность Exnum Corpses, когда она сама генерирует труп. Причем он не появляется рядом и она его поднимает, он сразу добавляется ей. Как их-то отловить? Только если выкинуть
Да, можно. Если знаешь как правильно выстроить случайное значение, то особого труда не составит построить определенный сценарий. Это можно реализовать через области, 3 изначальные области где будет выстраиваться тот или иной сценарий + через математический расчет координат областей можно выставить определенные предметы, но краше будет чистый "hardcore", выстраиваем случайное расположение точек, и в них что угодно, магазин, декор, и так далее...
На практике выглядит так:
При прогрузке карты выдаем случайное значение, которое имеет... скажем 3 триггера (3 комнаты). И в триггерах прописываем сценарий рендера локации комнаты, плюс триггер на эффект обитателя в области той или иной комнате.
Что за чушь ты тут описал? Просто когда спасатели прилетают, паузи таймер, а при перезапуске игры, запускай его по новой(с тем же ожиданием)
Кстати, идея норм. Можешь скинуть? А то я не удержусь, и стырю её у тебя :D
Нашёл систему, где звук передаётся в таймер, который истекает через 0 секунд. В результате один и тот же звук может проигрываться несколько раз без всяких проблем. В инетике пишут мол это такой баг движка.
Только дебаффы ядовитых стрел могут стакатся, но даммик обязан иметь дальнюю атаку (при условии что у разных абилок ядовитых стрел будут разные баффы в настройках).
Так же можно юзать таймер и ауру торнадо как написали выше, ну если уж совсем нужен сложный бафф как дефолтный - то тут триггер и немного гемора с мемхаком, зато полный комплект параметров (мигает иконка в статусе перед завершением время действия, бафф спадает с цели после диспела, смерти (у цели крест перерождения или аналог), складывается или не складывается в зависимости от кода).
Пример не рекомендуемый к повторению
function FormatAirportTrainingBar takes integer fp_n returns string
local string str = ""
if ( fp_n <= 0 ) then
return str
endif
loop
exitwhen fp_n < 10
if ( udg__TempBarStyle == 0 ) then
set str = str + "''''''''''"
else
set str = str + "||||||||||||||||||||"
endif
set fp_n = fp_n - 10
endloop
loop
exitwhen fp_n <= 0
if ( udg__TempBarStyle == 0 ) then
set str = str + "'"
else
set str = str + "||"
endif
set fp_n = fp_n - 1
endloop
return str
endfunction
function UpdateAirportTrainingBar takes texttag tt, integer fp_nTick, integer fp_nTickMax returns nothing
local integer nProgress
local integer nLen
local string strTT1
local string strTT2
if ( tt == null ) then
call BJDebugMsg( "text tag hDZzRwuZxFQcXqaMPnML null" )
return
endif
set nLen = R2I( I2R( fp_nTickMax ) / 300 * 100 )
set nProgress = R2I( I2R( nLen ) / fp_nTickMax * fp_nTick )
set strTT1 = "" + FormatAirportTrainingBar( nProgress )
set strTT2 = FormatAirportTrainingBar( nLen - nProgress ) + ""
call SetTextTagText( tt, "|cff0080c0" + strTT1 + "|r|cffff0000" + strTT2 + "|r", 0.023 )
endfunction
function Get_Staff_of_Purification takes unit runner returns item
set bj_forLoopAIndex = 0
set bj_lastCreatedItem = null
if GetUnitAbilityLevel( runner, 'Arun' ) == 0 then
return null
endif
loop
exitwhen bj_forLoopAIndex > 5
set bj_lastCreatedItem = UnitItemInSlot( runner, bj_forLoopAIndex )
if GetItemTypeId( bj_lastCreatedItem ) == 'I01A' then
return bj_lastCreatedItem
endif
set bj_forLoopAIndex = bj_forLoopAIndex + 1
endloop
return bj_lastCreatedItem
endfunction
function Trig_RunnerDamageDetect_Conditions takes nothing returns boolean
if GetTriggerEventId( ) == EVENT_UNIT_DAMAGED then
return GetEventDamage( ) > 0.00 and GetEventDamageSource( ) != GetTriggerUnit( ) and GetEventDamageSource( ) != DummyAttacker
endif
return true
endfunction
function HealRunner takes nothing returns nothing
local DamageData dd = GetDataBX( GetExpiredTimer( ) )
call UnitRemoveAbility( dd.attacked, 'AMhp' )
call SetUnitState( dd.attacked, UNIT_STATE_LIFE, dd.hp )
call RemoveDataBX( dd.trix )
call DestroyTimer( dd.trix )
call dd.clear( )
call dd.destroy( )
endfunction
function Trig_RunnerDamageLock_Actions takes nothing returns nothing
local TriggerData st = GetDataBX( GetTriggeringTrigger( ) )
local DamageData dd
local eventid id = GetTriggerEventId( )
if id == EVENT_GAME_TIMER_EXPIRED and st.id < st.time and st.attacked != null then
set st.id = st.id + 1
if GetUnitAbilityLevel( st.attacked, 'Bcyc' ) > 0 or GetUnitAbilityLevel( st.attacked, 'Bcy2' ) > 0 then
call SetTextTagPos( st.tt, GetUnitX( st.attacked ) - 60.00, GetUnitY( st.attacked ) - 60.00, 585.00 )
else
call SetTextTagPos( st.tt, GetUnitX( st.attacked ) - 60.00, GetUnitY( st.attacked ) - 60.00, 80.00 + GetUnitFlyHeight( st.attacked ) )
endif
call UpdateAirportTrainingBar( st.tt, 100 - R2I( st.dmg / st.hp * 100.00 ), 100 )
elseif id == EVENT_UNIT_DAMAGED and st.dmg < st.hp then
set dd = DamageData.create( )
set dd.trix = CreateTimer( )
set dd.attacked = st.attacked
set dd.dmg = GetEventDamage( )
set dd.hp = GetUnitState( dd.attacked, UNIT_STATE_LIFE )
call SetDataBX( dd.trix, dd )
call UnitAddAbility( dd.attacked, 'AMhp' )
call SetUnitState( dd.attacked, UNIT_STATE_LIFE, dd.hp + dd.dmg )
call TimerStart( dd.trix, 0.00, false, function HealRunner )
set st.dmg = st.dmg + dd.dmg
else
call UnitRemoveAbility( st.attacked, 'A08L' )
call UnitMakeAbilityPermanent( st.attacked, false, 'A08L' )
call DisableTrigger( st.trg )
call SetTextTagVisibility( st.tt, false )
if not IsUnitDead( st.attacked ) then
call UnitRemoveAbility( st.attacked, 'B00A' )
endif
call RemoveSavedInteger( gg_htb_HashData, ExKeySoPRunner, GetHandleId( st.attacked ) )
call st.RemoveTrigger( )
call st.destroy( )
endif
set id = null
endfunction
function Trig_Staff_of_Purification_Actions takes nothing returns nothing
local TriggerData dd
local unit Runner = GetSpellAbilityUnit( )
local integer RunnerId = GetHandleId( Runner )
local item Staff = LoadItemHandle( gg_htb_HashData, RunnerId, ExKeySoP )
local integer ChargesCount = 0
local trigger trig = LoadTriggerHandle ( gg_htb_HashData, ExAtomShield, RunnerId )
local integer pBuff
if Staff == null then
set Staff = Get_Staff_of_Purification( Runner )
if Staff == null then
//call DisplayTextToPlayer( Player( CrashPlayerNumber ), 0.00, 0.00, I2Sx( 'A01Q', CrashPlayerNumber ) )
call BJDebugMsg( DEBUG + I2Sx( 'A02O', 0 ) + INFO )
return
endif
call SaveBoolean( gg_htb_HashData, RunnerId, ExKeyHasStaff, true )
call SaveItemHandle( gg_htb_HashData, RunnerId, ExKeySoP, Staff )
endif
set ChargesCount = GetItemCharges( Staff )
if ChargesCount < 1 then
set Runner = null
set Staff = null
set trig = null
return
endif
call SetItemCharges( Staff, 0 )
if trig != null then // блокирующие урон способности не складываются.
call TriggerExecute( trig )
set trig = null
endif
set dd = TriggerData.create( )
set dd.attacked = Runner
set dd.pl = GetOwningPlayer( Runner )
set dd.trg = CreateTrigger( )
set dd.trc = TriggerAddCondition( dd.trg, Condition( function Trig_RunnerDamageDetect_Conditions ) )
set dd.tra = TriggerAddAction ( dd.trg, function Trig_RunnerDamageLock_Actions )
set dd.tt = CreateTextTag( )
set dd.hp = 1000.00 * ChargesCount
set dd.dmg = 1.00
set dd.id = 0
set dd.time = 480
set dd.c = 0.03125
call UnitAddAbility( Runner, 'A07E' )
call UnitRemoveAbility( Runner, 'A07E' )
call UnitAddAbility( Runner, 'A08L' )
call UnitMakeAbilityPermanent( Runner, true, 'A08L' )
call SetDataBX( dd.trg, dd )
call SaveInteger( gg_htb_HashData, ExKeySoPRunner, RunnerId, dd )
call TriggerRegisterPlayerEvent( dd.trg, dd.pl, EVENT_PLAYER_LEAVE )
call TriggerRegisterDeathEvent( dd.trg, Runner )
call TriggerRegisterUnitEvent( dd.trg, Runner, EVENT_UNIT_DAMAGED )
call TriggerRegisterTimerEvent( dd.trg, 0.03125, true )
if GetLocalPlayer( ) == dd.pl or IsPlayerAlly( GetLocalPlayer( ), dd.pl ) then
call SetTextTagVisibility( dd.tt, true )
else
call SetTextTagVisibility( dd.tt, false )
endif
set pBuff = GetUnitAbility( dd.attacked, 'B00A' ) + 0x90
set dd.c = TimerGetElapsed( DispTimer )
call WMem( RMem( pBuff ) + 0x4, mR2I( dd.c + 15.10 ) )
call WMem( RMem( pBuff ) + 0x8, mR2I( dd.c + 10.408 ) )
call SetBuffLevel( pBuff - 0x90, ChargesCount )
call UpdateAirportTrainingBar( dd.tt, 100, 100 )
set Runner = null
endfunction
//===========================================================================
function InitTrig_Staff_of_Purification takes nothing returns nothing
set udg__TempBarStyle = 0
endfunction
Выше пример баффа для предмета, который образует щит блокирующий урон, кол-во заблокированного урона и сколько еще заблокирует щит отображается над головой героя, в виде полоски здоровья (только цвет сине-красный). Так же в статуе есть бафф, один в 1 как бафф дефектных способностей вара, не складывается - новый, перебивает старый. И так далее...
Пока нет желания разбираться, что у тебя так, а что не так. Но вижу, что переменная Window не назначена окну, а ещё как бы создаются в цикле одновременно 10 окон, которые потом все одновременно ждут 50 секунд. Вот скрин действий триггера вместо двух твоих, секунда ожидания поставлена для того, чтобы увидеть пропадание окна таймера.
Если еще немного покопатса на сайте в разделе декораций - можно нагрести кучу добра!
И вобще мой вам совет - научитесь минимальному моделингу: сможете клепать такие вещи за 3 минуты на коленке с необходимым вам видом, формой и текстурой.
Если еще немного покопатса на сайте в разделе декораций - можно нагрести кучу добра!
И вобще мой вам совет - научитесь минимальному моделингу: сможете клепать такие вещи за 3 минуты на коленке с необходимым вам видом, формой и текстурой.
хочешь популярности и крупный донат?? Тогда редактор варика - точно не тот инструмент для тебя. Кроме ностальгирующих ветеранов в варик никто особо не играет, а эти сами ветераны повидали всякое, едва ли ты их удивишь настолько, что о тебе будут говорить. Замечание о выходе обновления на вар3 не вызвало даже тени мысли у приятелей-некогда-перводотеров-и-кастомных-карт-игроков снова установить варкрафт(я даже не сказал им что обновление по сути ничего не делает, просто что вышло обновление). Может только мне так везёт, но мои печальные наблюдения в том, что варик медленно но верно теряет игроков.
По крайней мере слово "перспектива" тут явно чужое.
легко сделать, чего сложного то? там с зарядами итема работаешь. Нужно знать в какой момент вычитать (при событий - юнит атакован? просто юнит атакован происходит тогда, когда юнит начинает замахиваться, стрелять. )
Да, к сожалению последние дни захожу не очень часто :). У меня дочь родилась недавно, за компом вообще маловато времени теперь провожу.
По сабжу:
Там же играем, на айсикапе, только канал сменили, на AoIE, без приставки "op ".
(для перехода к нам в игре команда /join aoie в чате на любом канале)
Aws, тогда мой вариант тебе идеально подходит, осталось решить какой необратимый хеш одновременно достаточно хорош и не слишком сложен в реализации. Я помню кто-то даже md5 на jass выкладывал тут на xgm, но, имхо, это изврат.
Принцип примерно такой:
игрок вводит команду вида "-code qwerty", где code это или универсальное ключевое слово для ввода кодов или уникальное для каждого кода, в зависимости от реализации, а qwerty это ключевое слово для конкретного кода
триггер отлавливает ввод первого ключевого слова "-code" и выделяет из строки второе ключевое слово "qwerty"
ключевое слово "qwerty" прогоняется через необратимую хеш-функцию и превращается в хеш "123456"
хеш "123456" сравнивается с записаным в карте хешем, циклом если команда "-сode" универсальная, или напрямую если у каждого кода есть своя команда
если хеш совпал, то выдаем плюшки, ну а если нет, то шлем нах
при попытке вскрыть карту кулхацкер обнаружит только "-code" и "123456", но не "qwerty", а значит не сможет правильно ввести команду в официальной версии карты
наличие алгоритма хеширования в карте не спасает кулхацкера т.к. алгоритм необоратимый и не может из "123456" получить "qwerty"
кулхацкер может поробовать подобрать ключевое слово, хеш которого совпадет с "123456", но если функция хеширования достаточно хороша, то он скорее начнет рвать волосы на жопе и визжа кататься по полу, чем у него это получится
Короче, я вообще не понял ничего, вроде и на вопрос не ответили, и при этом много интересного написали. Я так понял красная цифра это урон до поглощения бронёй. Конец.
xgm.guru/p/100/192363?postid=352424#comment2с помощью приказов. Используй нктивки с имитацией' там где с магазином. Ещё нужно кучу проверок делать (есть ли ресурсы, хватает пищи и др). Вдруг пригодится
Есть две разные вещи - тренировка и покупка (найм). При тренировке ты можешь заставить здание само начать обучать войска' а вот при найме нужно чтобы к магазину подошёл юнит и он был выбран магазином (точно не уверен нужен ли здесь нацеливать выбор магазинчика, через приказ smart кажись нацеливает выборку на юнита, если правильно понял пример Warden. Приказ возвращает boolean, если что). Смотри в ссылке пример Warden-a
Понимаешь, вроде когда герой выбирает через smart магазин, у игрока на панеле по идее должны быть изображены итемы или юниты, которых продают. Вроде герой должен выбирать магазин, а не наоборот?! Странно. Хотя, попробуй ещё героем выбрать. Хотя это комп.
Nyanta, для начала дебаг сделать как написано в статье
Сделал. Триггер работает как нужно. При входе всегда пишет "Вход!", при выходе - "Выход!". Порядок текста не меняется.
В общем, проблема, почему-то, была в названии анимации. Открыл модель через MdlVis и назвал анимации "родными" словами Stand, Walk, Death. Стало работать как надо.
Спасибо Rare за Rare:
ставь скорость анимации на 0%
И nvc123 за то, что натолкнул на мысль этим) nvc123:
Ошибка при работе с MdlVis. Попробуй открыть модель в версии 1.40, там должно изменение видимости в ключевых кадрах должно заработать. Однако советую сделать копию модели, т.к. 1.40, если не изменяет память, ломает уже настроенную видимость.
Анимация кости базы при death сместилась у конечной точки в линейке анимации. Поправил. В игре потестил, работает. Рассчитать границы нужны когда делаешь новые или изменяешь старые анимации, одна из причин чтоб анимация не сместилась и была на своем месте. Но в твоем случае она сразу не помогла.
Насколько я понял, тебе нужно просто сменить текстуру. Для этого тебе по меньшей мере нужна текстура. Можно взять либо стандартную, либо создать самому (что довольно просто, если знать как).
Чтобы создать текстуру, возьми любое изображение, открой его в ФШ и сохрани как tga 32 бит с размером до 512х512 (вроде бы можно делать любой размер, не превышающий 1024х768, но я советую сохранять пропорции и делать размер не больше 512х512, или кратных половине этого числа (256/128/64/32) , за тем открой в War3 Image Extractor и переведи формат tga в blp. Потом открываешь модельку - редактор текстур и переименовываешь нужную текстуру в ту которая тебе нужна (они должны быть в одной папке) жмешь - Enter - .
ClotPh, Герой беру с проверкой тип героя. Но возврашает 0 даже расчет бонус атака от статы тоже фаталит 0_о
Извиняюсь это моя ошибка то что я его не сохранил unit в структуру а то получал пустой юнит...
RMem/WMem - вторая версия, есть еще третья и, скорее всего, последняя
function SetAbilityStringParam2 takes integer id, integer off, string newVal, integer lvl returns boolean
local integer k=GetAbilityUIDefCaching(id)
if k < 1 then
return false
endif
set k=k+off
set k=RMem(k)
if k>0 then
set k=k+lvl*4-4
call AddNewOffsetToRestoreFast(k)
call WMem(k,GetStringAddress(newVal))
return true
endif
return false
endfunction
ИИ стандартный, полагаю? Стандартному ИИ вроде как вижн не важен, он и так знает где все находятся, если мне не изменяет память. Как от него не прячься, найдет сразу. Если уж очень хочется - давать юнитов нейтралам и делать их союзным всем ботам. (игроков 16, если не изменяет память). Или давать союзным игрокам, при наличии. По крайней мере не будут мчаться в след за армией. Однако вполне могут быть более качественные решения проблемы, я стандартный ИИ не изучал, не могу быть уверен в офигительности предложенного решения. :)
К сожалению, таким способом будут работать только башни, улучшенные до Башни Стрелка во время игры. Если изначально на карте стоят Башни Стрелки, они работать не будут. Если надо могу исправить.
Исправил. Теперь Башни Стрелки, поставленные на карту в редакторе будут работать так же, как те, что были улучшены во время игры.
незнаю поможет или нет но пробни через кустом скрипт написать это AddUnitAnimationProperties(u, "Alternate", false)
где u - это твой юнит и советую перед ней поставить паузу тригера на 0.1 хотяб
koloff:
Объявляются переменные в начале.
local lightning l
call AddLightningEx(codeName, true, GetLocationX(where1), GetLocationY(where1), GetLocationZ(where1), GetLocationX(where2), GetLocationY(where2), GetLocationZ(where2))
set l = bj_lastCreatedLightning
» WarCraft 3 / Управление крипами
» WarCraft 3 / Телепортация
» WarCraft 3 / JNGP не работает(
» WarCraft 3 / Панель...
» WarCraft 3 / Проблема с открытием карты
» WarCraft 3 / ИИ использование способностей
» WarCraft 3 / Помогите решить проблему с С++
» WarCraft 3 / На 90 градусов...
» WarCraft 3 / Дыхание...
» WarCraft 3 / Перестала работать инициализация
» WarCraft 3 / почему может не работать?
» WarCraft 3 / Ответе пожалуйста на несколько моих вопросов...
» WarCraft 3 / Абилка ботинка
» WarCraft 3 / Мгновенный поворот юнита
» WarCraft 3 / Вопрос по трупам
» WarCraft 3 / Проблема с таймером
» WarCraft 3 / Нужны модели
» WarCraft 3 / Про проекты
» WarCraft 3 / Инком от удара...
» WarCraft 3 / Таверна
» WarCraft 3 / Проблема с анимациями
» WarCraft 3 / Опыт для любого юнита (не героя)
» WarCraft 3 / Вопрос по модели...
» WarCraft 3 / Не работает мемхак
» WarCraft 3 / Проблема с москитами